/*
================================================================================
	Plik: mem_abs.c
--------------------------------------------------------------------------------
	Autorzy: Piotr Zdunek, Mateusz Słowikowski, Krzysztof Wiąckowski
	Projekt:Model mikrokontrolera AVR
	Kompilator: avr-gcc-4.3.5
	Doc: doxygen 1.7.4
--------------------------------------------------------------------------------
	Zawiera:
--------------------------------------------------------------------------------
	Komentarze:
================================================================================
*/

#include <stdio.h>
#include "types.h"
// -----------------------------------------------------------------------------
// GLOBAL TABLES
// -----------------------------------------------------------------------------
uint16_t MEMC[MAX_ADDRESS + 1]; //obszar pamięci kodu
uint8_t MEMD[MAX_ADDRESS + 1]; //obszar pamięci danych
// -----------------------------------------------------------------------------
// GLOBAL VARIABLE
// -----------------------------------------------------------------------------
uint16_t PC; //licznik rozkazów

//uint8_t    FLAGS;						//flagi procesora 8 bitowy rejestr SREG


void loadMEMC(char *file) { //zadowanie pamięci kodu z pliku
	FILE *file_ptr;
	file_ptr = fopen(file, "rb");
	if (!file_ptr) {
		printf("MEMC file not found (%s)!\n", file);
		exit(-2);
	}
	fseek(file_ptr, 0, SEEK_SET);
	fread(MEMC, MAX_ADDRESS + 1, 1, file_ptr);
	fclose(file_ptr);
}

void loadMEMD(char *file) { //zadowanie pamięci danych z pliku
	FILE *file_ptr;
	file_ptr = fopen(file, "rb");
	if (!file_ptr) {
		printf("MEMD file not found (%s)!\n", file);
		exit(-3);
	}
	fseek(file_ptr, 0, SEEK_SET);
	fread(MEMD, MAX_ADDRESS + 1, 1, file_ptr);
	fclose(file_ptr);
}

void saveMEMD(char *file) { //zapisz zawartość pamięci danych do pliku
	FILE *file_ptr;
	file_ptr = fopen(file, "wb");
	if (!file_ptr) {
		printf("MEMD cannot open to write (%s)!\n", file);
		exit(-3);
	}
	fseek(file_ptr, 0, SEEK_SET);
	fwrite(MEMD, MAX_ADDRESS + 1, 1, file_ptr);
	fclose(file_ptr);
}

uint8_t getMEMD(uint16_t p) {
	return MEMD[p];
}

void printMEMD() {
	int i = 0;
	printf("MEMD\n");
	for (i = 0; i < PRINT_MEMD_NUMBER; i++)
		printf("%d\n", getMEMD(i));

}

uint16_t getMEMC(uint16_t p) {
	return MEMC[p];
}

void printMEMC() {
	int i = 0;
	printf("MEMC\n");
	for (i = 0; i < PRINT_MEMC_NUMBER; i++)
		printf("0x%04x\n", getMEMC(i));

}

void setPC(uint16_t v) {
	PC = v;
}

uint16_t getPC(void) {
	return PC;
}

void incPC(void) {
	PC++;
}

void incPC_k(int k) {
	if( k > 63 ){
		k = k - 128;
		//printf("LALA k = %d\n", k);
		PC -= k - 1;
	}else {
		PC += k + 1;
	}
}

uint8_t getRegister(int n) {
	if (n > 31) {
		printf("Error. Exceeded maximal register address.");
		while (1)
			;
	} else
		return MEMD[n];
}

uint8_t GetRegisterFromDataSpace(int n) {
	if (n > 65635) {
		printf("ERROR. MAXIMUM ADRESS EXCEEDED.");
		return -1;
	} else
		return MEMD[n];
}

uint16_t GetYRegister() {
	uint16_t Y;
	Y = (getRegister(HYR) << 8) + get(LYR);
	return Y;
}

void SaveYRegister(uint16_t ADDRESS) {
	MEMD[HYR] = (ADDRESS) >> 4;
	MEMD[LYR] = (ADDRESS & 0x0F);
}

void incY() {
<<<<<<< .mine
	uint16_t Y;
	//printf("YH = 0x%04x, YL = 0x%04x\n", getRegister(HYR), getRegister(LYR));
	Y = (getRegister(HYR) << 4) + getRegister(LYR);
	//printf("Y = 0x%04x\n", Y);
	Y++;
	SaveYRegister(Y);
}
void decY() {
	uint16_t Y;
	//printf("YH = 0x%04x, YL = 0x%04x\n", getRegister(HYR), getRegister(LYR));
	Y = (getRegister(HYR) << 4) + getRegister(LYR);
	//printf("Y = 0x%04x\n", Y);
	Y--;
	SaveYRegister(Y);
}
=======
	uint16_t Z;
	Z = (getRegister(HYR) << 8) + get(LYR);
	return Z;
>>>>>>> .r18

void displaceY(uint8_t k) {
	uint16_t Y;
	//printf("YH = 0x%04x, YL = 0x%04x\n", getRegister(HYR), getRegister(LYR));
	Y = (getRegister(HYR) << 4) + getRegister(LYR);
	//printf("Y = 0x%04x\n", Y);
	Y += k;
	SaveYRegister(Y);
}

uint16_t GetZRegister() {
uint16_t Z;
Z = (getRegister(HZR) << 4) + getRegister(LZR);
return Z;
}

void SaveZRegister(uint16_t ADDRESS) {
	MEMD[HZR] = (ADDRESS) >> 4;
	MEMD[LZR] = (ADDRESS & 0x0F);
}

void incZ() {
	uint16_t Z;
	//printf("YH = 0x%04x, YL = 0x%04x\n", getRegister(HYR), getRegister(LYR));
	Z = (getRegister(HZR) << 4) + getRegister(LZR);
	//printf("Y = 0x%04x\n", Y);
	Z++;
	SaveZRegister(Z);
}
void decZ() {
	uint16_t Z;
	//printf("ZH = 0x%04x, YZ = 0x%04x\n", getRegister(HZR), getRegister(LZR));
	Z = (getRegister(HZR) << 4) + getRegister(LZR);
	//printf("Z = 0x%04x\n", Z);
	Z--;
	SaveZRegister(Z);
}

void displaceZ(uint8_t k) {
	uint16_t Z;
	//printf("YH = 0x%04x, YL = 0x%04x\n", getRegister(HYR), getRegister(LYR));
	Z = (getRegister(HZR) << 4) + getRegister(LZR);
	//printf("Y = 0x%04x\n", Y);
	Z += k;
	SaveZRegister(Z);
}

void setRegister(int n, uint8_t v) {
if (n > 31) {
	printf("Error. Exceeded maximal register address.");
} else
	MEMD[n] = v;
}

void SaveFlagRegister(uint8_t FLAGS) {
MEMD[SREG_ADDRESS] = FLAGS;
}

void SaveRegister(uint8_t VALUE, uint16_t ADDRESS) {
MEMD[ADDRESS] = VALUE;
}

uint8_t GetFlagRegister() {
uint8_t FLAGS;
FLAGS = MEMD[SREG_ADDRESS];

#if DEBUG_MODE
printf("MEMD[%d] = %d\n",SREG_ADDRESS,MEMD[SREG_ADDRESS]);
#endif

return FLAGS;
}

//Funkcja GetFlagStatus sprawdza czy dany bit rejestru SREG jest ustawiony na 0 czy na 1
//i zwraca tę wartość na wyjście. Można to porównać z FALSE, TRUE.

uint8_t GetFlagRegisterStatus(int n) {
//pobranie rejestru flag z pamięci
uint8_t FLAGS = GetFlagRegister();
uint8_t FLAGS_TEMP;
FLAGS_TEMP = (FLAGS & (1 << n)) >> n;

return FLAGS_TEMP;

}

uint8_t GetRegisterBitStatus(uint8_t Rd, int n) {

	uint8_t Rd_temp;
//pobranie rejestru flag z pamięci
	Rd_temp = (Rd & ~(0 << n)) >> n;
	return Rd_temp;

}

<<<<<<< .mine
void PrintFlagRegisterStatus() {
uint8_t I = GetFlagRegisterStatus(FLAG_I); // SREG_MASK = 128
uint8_t T = GetFlagRegisterStatus(FLAG_T); //	SREG_MAS = 64
uint8_t H = GetFlagRegisterStatus(FLAG_H); //	SREG_MAS = 32
uint8_t S = GetFlagRegisterStatus(FLAG_S); //	SREG_MAS = 16
uint8_t V = GetFlagRegisterStatus(FLAG_V); //	SREG_MAS = 8
uint8_t N = GetFlagRegisterStatus(FLAG_N); //	SREG_MAS = 4
uint8_t Z = GetFlagRegisterStatus(FLAG_Z); //	SREG_MAS = 2
uint8_t C = GetFlagRegisterStatus(FLAG_C); //	SREG_MAS = 1
printf("SREG STATUS\n");
printf("I = %d\nT = %d\nH = %d\nS = %d\nV = %d\nN = %d\nZ = %d\nC = %d\n", I,
		T, H, S, V, N, Z, C);
=======
void PrintFlagRegisterStatus(){  //do debugowania
	uint8_t I = GetFlagRegisterStatus( FLAG_I );			// SREG_MASK = 128
	uint8_t T = GetFlagRegisterStatus( FLAG_T );			//	SREG_MAS = 64
	uint8_t H = GetFlagRegisterStatus( FLAG_H );			//	SREG_MAS = 32
	uint8_t S = GetFlagRegisterStatus( FLAG_S );			//	SREG_MAS = 16
	uint8_t V = GetFlagRegisterStatus( FLAG_V );			//	SREG_MAS = 8
	uint8_t N = GetFlagRegisterStatus( FLAG_N );			//	SREG_MAS = 4
	uint8_t Z = GetFlagRegisterStatus( FLAG_Z );			//	SREG_MAS = 2
	uint8_t C = GetFlagRegisterStatus( FLAG_C );			//	SREG_MAS = 1
	printf("SREG STATUS\n");
	printf("I = %d\nT = %d\nH = %d\nS = %d\nV = %d\nN = %d\nZ = %d\nC = %d\n",I,T,H,S,V,N,Z,C);
>>>>>>> .r18

}

void SetFlagRegisterBit(int n) {
//Pobranie rejestru flag z pamięci
uint8_t FLAGS;
FLAGS = GetFlagRegister();
FLAGS = FLAGS | (1 << n);
//Zapis rejestru do pamięci
SaveFlagRegister(FLAGS);
}

uint8_t SetRegisterBit(uint8_t Rd, int n) {

	Rd = Rd | (1 << n);

	return Rd;
}

void ClearFlagRegisterBit(int n) {
//Pobranie rejestru flag z pamięci
uint8_t FLAGS;
FLAGS = GetFlagRegister();
//Wyczyszczenie odpowiedniego bitu
FLAGS = (FLAGS & ~(1 << n));

//Zapis rejestru do pamięci
SaveFlagRegister(FLAGS);
}

uint8_t ClearRegisterBit(uint8_t Rd,int n) {
//Wyczyszczenie odpowiedniego bitu
Rd = (Rd & ~(1 << n));

//Zwrócenie rejestru
return Rd;
}

void SetFlagRegister(uint8_t FLAGS_TMP) {
//Pobranie rejestru flag z pamięci
uint8_t FLAGS;
FLAGS = GetFlagRegister();

FLAGS = FLAGS_TMP;

//Zapis rejestru do pamięci
SaveFlagRegister(FLAGS);
}

void InitializeFlagRegister() {
MEMD[SREG_ADDRESS] = 0;
}

